package com.example.housingRentalSystem.service.Impl;

import com.example.housingRentalSystem.bean.Role;
import com.example.housingRentalSystem.bean.User;
import com.example.housingRentalSystem.mapper.RoleMapper;
import com.example.housingRentalSystem.mapper.UserMapper;
import com.example.housingRentalSystem.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class UserServiceImpl implements UserService, UserDetailsService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public UserServiceImpl(UserMapper userMapper, RoleMapper roleMapper, PasswordEncoder passwordEncoder) {
        this.userMapper = userMapper;
        this.roleMapper = roleMapper;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {
        try {
            logger.debug("Attempting to load user by username: {}", account);
            User user = userMapper.findByAccount(account);
            if (user == null) {
                logger.error("User not found for username: {}", account);
                throw new UsernameNotFoundException("用户名未找到: " + account);
            }

            if (user.getStatus() == 2) {
                logger.error("Account disabled for username: {}", account);
                throw new RuntimeException("您的账户已被禁用，请联系管理员。");
            }
            if (user.getIsDel() == 2) {
                logger.error("Account deleted for username: {}", account);
                throw new RuntimeException("您的账户已被删除，请联系管理员。");
            }

            Set<Role> roles = new HashSet<>(userMapper.findRolesByUserId(user.getId()));
            List<SimpleGrantedAuthority> authorities = new ArrayList<>();
            for (Role role : roles) {
                authorities.add(new SimpleGrantedAuthority(role.getName()));
            }
            logger.debug("Loaded user details for username: {}, roles: {}", account, roles);
            return new org.springframework.security.core.userdetails.User(
                    user.getAccount(),
                    user.getPassword(),
                    authorities
            );
        } catch (Exception e) {
            logger.error("Error loading user by username: {}", account, e);
            throw new InternalAuthenticationServiceException("内部认证服务错误", e);
        }
    }

    @Override
    public User findByAccount(String account) {
        return userMapper.findByAccount(account);
    }

    @Override
    public void save(User user) {
        if (findByAccount(user.getAccount()) != null) {
            throw new RuntimeException("账户已存在");
        }
        if (findByAccount(user.getNickname()) != null) {
            throw new RuntimeException("昵称已存在");
        }
        String encodedPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        userMapper.insert(user);
    }

    @Override
    public void resetPwd(User user) {
        User existingUser = findByAccount(user.getAccount());
        if (existingUser == null) {
            throw new RuntimeException("账户不存在");
        }
        if (existingUser.getStatus() == 2) {
            throw new RuntimeException("您的账户已被禁用，请联系管理员。");
        }
        if (existingUser.getIsDel() == 2) {
            throw new RuntimeException("您的账户已被删除，请联系管理员。");
        }
        if (!Objects.equals(existingUser.getPhone(), user.getPhone())) {
            throw new RuntimeException("手机号不正确");
        }
        if (!Objects.equals(existingUser.getEmail(), user.getEmail())) {
            throw new RuntimeException("邮箱不正确");
        }
        if (existingUser.getIdcard() == null || existingUser.getIdcard().length() < 6) {
            throw new RuntimeException("身份证号不完整");
        }
        String existingIdCardLastSix = existingUser.getIdcard().substring(existingUser.getIdcard().length() - 6);
        if (!existingIdCardLastSix.equals(user.getIdCardLastSix())) {
            throw new RuntimeException("身份证后六位不正确");
        }
        String encodedPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);
        userMapper.resetPwd(user);
    }

    @Override
    @Transactional
    public void changePassword(String account, String oldPassword, String newPassword) {
        User user = userMapper.findByAccount(account);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }

        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new BadCredentialsException("旧密码错误");
        }

        user.setPassword(passwordEncoder.encode(newPassword));
        int rows = userMapper.updatePassword(user);

        if (rows == 0) {
            throw new RuntimeException("密码更新失败");
        }
    }

    @Override
    public User updateUserInfo(User user) {
        User existingUser = userMapper.findByAccount(user.getAccount());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }

        if (user.getNickname() != null) {
            existingUser.setNickname(user.getNickname());
        }
        if (user.getPhone() != null) {
            existingUser.setPhone(user.getPhone());
        }
        if (user.getEmail() != null) {
            existingUser.setEmail(user.getEmail());
        }
        if (user.getJob() != null) {
            existingUser.setJob(user.getJob());
        }
        if (user.getHobby() != null) {
            existingUser.setHobby(user.getHobby());
        }
        if (user.getDescription() != null) {
            existingUser.setDescription(user.getDescription());
        }

        int rows = userMapper.updateUserInfo(existingUser);
        if (rows == 0) {
            throw new RuntimeException("更新失败");
        }

        return userMapper.findByAccount(user.getAccount());

    }

    public void addRoleToUser(String account, String roleName) {
        User user = userMapper.findByAccount(account);
        Role role = roleMapper.findByName(roleName);
        if (user != null && role != null) {
            roleMapper.insertUserRole(user.getId(), role.getId());
        }
    }

    @Override
    public User findUserInfoByAccount(String account) {
        User user = userMapper.findUserInfoByAccount(account);
        if (user != null) {
            user.setPassword(null);
            user.setIsDel(null);
            user.setStatus(null);
        }
        return user;
    }
    @Override
    @Transactional
    public void updateAvatar(String account, String avatar) {
        int rows = userMapper.updateAvatar(account, avatar);
        if (rows == 0) {
            throw new RuntimeException("头像更新失败");
        }
    }

    @Override
    public Integer getUserIdByAccount(String account) {
        User user = userMapper.findByAccount(account);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        return user.getId();
    }


    @Override
    public List<User> getUsersByRole(String roleName) {
        List<User> users = userMapper.findUsersByRoleName(roleName);
        // 过滤敏感信息
        users.forEach(user -> {
            user.setPassword(null);
            user.setIsDel(null);
        });
        return users;
    }
    @Override
    @Transactional
    public void updateUserStatus(Integer userId, Integer status) {
        int rows = userMapper.updateUserStatus(userId, status);
        if (rows == 0) {
            throw new RuntimeException("用户状态更新失败");
        }
    }
    @Override
    @Transactional
    public void resetPassword(Integer userId) {
        String defaultPassword = passwordEncoder.encode("123456");
        int rows = userMapper.resetUserPassword(userId, defaultPassword);
        if (rows == 0) {
            throw new RuntimeException("密码重置失败");
        }
    }

    @Override
    public int selectUserCount() {
        int count = userMapper.selectUserCount();
        return count;
    }


}